﻿using Microsoft.Extensions.Caching.Memory;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.Json;
using System.Threading.Channels;
using System.Threading.Tasks;

namespace daonaite.core.Catche
{
    /// <summary>
    /// 本地缓存
    /// </summary>
    public class LocalCache : ICacheHelp
    {
        private readonly IMemoryCache cache;

        public LocalCache(IMemoryCache cache)
        {
            this.cache = cache;
        }

        /// <summary>
        /// 设置缓存,永不过期
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key"></param>
        /// <param name="data"></param>
        public void set<T>(string key, T data, int databse = 0)
        {
            var content = JsonSerializer.Serialize(data);
            cache.Set($"{key}{databse}", content);
        }

        /// <summary>
        /// 设置缓存
        /// </summary>
        /// <typeparam name="T">数据类型</typeparam>
        /// <param name="key">key</param>
        /// <param name="data">数据</param>
        /// <param name="ExpirationTime">过期时间,秒</param>
        public void set<T>(string key, T data, int ExpirationTime, int databse = 0)
        {
            var content = JsonSerializer.Serialize(data);
            cache.Set($"{key}{databse}", content, TimeSpan.FromSeconds(ExpirationTime));
        }

        /// <summary>
        /// 获取缓存值
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key"></param>
        /// <returns></returns>
        public T? get<T>(string key, int databse = 0)
        {
            string? content = cache.Get<string>($"{key}{databse}");
            if (content == null)
            {
                return default(T);
            }
            return JsonSerializer.Deserialize<T>(content);
        }

        /// <summary>
        /// 删除key
        /// </summary>
        /// <param name="key"></param>
        public void remove(string key, int databse = 0)
        {
            cache.Remove($"{key}{databse}");
        }

        /// <summary>
        /// 左侧入= 右侧入 ,本地版本只能左入右出
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key"></param>
        /// <param name="data"></param>
        /// <exception cref="NotImplementedException"></exception>
        public void listleftPush<T>(string key, T data, int databse = 0)
        {
            var ch = cache.Get<Channel<string>>($"{key}{databse}");
            if (ch == null)
            {
                ch = Channel.CreateUnbounded<string>();
            }
            var content = JsonSerializer.Serialize(data);
            ch.Writer.TryWrite(content);
            cache.Set($"{key}{databse}", ch);

        }

        /// <summary>
        /// 右侧入 = 左侧入 ,本地版本只能左入右出
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key"></param>
        /// <param name="data"></param>
        /// <exception cref="NotImplementedException"></exception>
        public void listrightPush<T>(string key, T data, int databse = 0)
        {
            var ch = cache.Get<Channel<string>>($"{key}{databse}");
            if (ch == null)
            {
                ch = Channel.CreateUnbounded<string>();
            }
            var content = JsonSerializer.Serialize(data);
            ch.Writer.TryWrite(content);
            cache.Set($"{key}{databse}", ch);
        }

        /// <summary>
        /// 左侧出 = 右侧入 ,本地版本只能左入右出
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public T? listleftPop<T>(string key, int databse = 0)
        {
            var ch = cache.Get<Channel<string>>($"{key}{databse}");
            if (ch == null)
            {
                return default(T);
            }
            string content = "";
            bool b = ch.Reader.TryRead(out content!);
            if (!b)
            {
                return default(T);
            }

            cache.Set($"{key}{databse}", ch);
            return JsonSerializer.Deserialize<T>(content);
        }

        /// <summary>
        /// 右侧出 = 左侧入 ,本地版本只能左入右出
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public T? listrightPop<T>(string key, int databse = 0)
        {
            var ch = cache.Get<Channel<string>>($"{key}{databse}");
            if (ch == null)
            {
                return default(T);
            }
            string content = "";
            bool b = ch.Reader.TryRead(out content!);
            if (!b)
            {
                return default(T);
            }

            cache.Set($"{key}{databse}", ch);
            return JsonSerializer.Deserialize<T>(content);
        }

        /// <summary>
        /// 查询list 数量
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public int listcount(string key, int databse = 0)
        {
            var ch = cache.Get<Channel<string>>($"{key}{databse}");
            if (ch == null)
            {
                return 0;
            }
            return ch.Reader.Count;
        }
    }
}
